#ifndef GAME_HPP
#define GAME_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/Graphics/Color.hpp>

#include <SmegTools/Config.h>
#include <SmegTools/Pattern/Singleton.hpp>

#include <SmegTools/Debug/DebugNew.hpp>

namespace sf {
    class RenderWindow;
    class VideoMode;
}

namespace smeg {
    namespace math {
        class BoundingBox;
    }
    namespace core {
        class DefaultGameImpl;

////////////////////////////////////////////////////////////
/// Represents a base Game with the classic game loop
////////////////////////////////////////////////////////////
class Game : public tools::Singleton< Game >
{
    DECLARE_SINGLETON( Game )

public:

    ////////////////////////////////////////////////////////////
    /// Init the game
    ///
    /// \param _GameImpl :  Game implementation object
    /// \param _Mode :      Video mode to use (defines the width, height and depth of the rendering area of the window)
    /// \param _pTitle :    Title of the window
    /// \param _Region :    Activate QuadTree partitionning by setting a region
    /// \param _uFrameRateLimit : Framerate limit
    /// \param _Style :     Window style
    /// \param _Settings :  Additional settings for the underlying OpenGL context
    ///
    ////////////////////////////////////////////////////////////
    void                Init(   const DefaultGameImpl& _GameImpl, 
                                sf::VideoMode _Mode, 
                                const char* _pTitle, 
                                unsigned _uFrameRateLimit = 60,
                                sf::Uint32 _Style = sf::Style::Default, 
                                const sf::ContextSettings& _Settings = sf::ContextSettings() );
    void                Init(   const DefaultGameImpl& _GameImpl, 
                                sf::VideoMode _Mode, 
                                const char* _pTitle, 
                                const math::BoundingBox& _Region,
                                unsigned _uFrameRateLimit = 60,
                                sf::Uint32 _Style = sf::Style::Default, 
                                const sf::ContextSettings& _Settings = sf::ContextSettings() );

    ////////////////////////////////////////////////////////////
    /// DeInit the game
    ///
    ////////////////////////////////////////////////////////////
    void                DeInit();

    ////////////////////////////////////////////////////////////
    /// Game loop
    ///
    ////////////////////////////////////////////////////////////
    void                GameLoop();

    /*********************** Accessors ************************/
    sf::RenderWindow*   GetRenderWindow() const;

    void                ChangeFramerateLimit( unsigned _uFrameRateLimit );
    const sf::Time&     GetElapsedTime() const;

    void                SetClearColor( const sf::Color& _Color );
    const sf::Color&    GetClearColor() const;

protected:
    /******************* Protected members ********************/
    DefaultGameImpl*    m_pGameImpl;
    sf::RenderWindow*   m_pRenderWindow;

    sf::Clock           m_GameClock;
    sf::Time            m_LastFrameTime;

    sf::Color           m_ClearColor;
};

/************************** Inline ************************/
inline sf::RenderWindow* Game::GetRenderWindow() const {
    return m_pRenderWindow;
}

inline const sf::Time& Game::GetElapsedTime() const {
    return m_LastFrameTime;
}

inline void Game::SetClearColor( const sf::Color& _Color ) {
    m_ClearColor = _Color;
}

inline const sf::Color& Game::GetClearColor() const {
    return m_ClearColor;
}

    } // namespace core
} // namespace smeg

#include <SmegTools/Debug/DebugNewOff.hpp>

#endif // GAME_HPP
